package com.ecoolex.chinadutyfree.retailer.admin.graphql;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;

import com.ecoolex.chinadutyfree.retailer.admin.core.AdminConstant;
import com.ecoolex.chinadutyfree.retailer.entity.Coupon;
import com.ecoolex.chinadutyfree.retailer.entity.CouponClass;
import com.ecoolex.chinadutyfree.retailer.entity.CouponClassExpireStrategy;
import com.ecoolex.chinadutyfree.retailer.entity.CouponVerifyingConsumption;
import com.ecoolex.chinadutyfree.retailer.enums.CouponClassProvideStrategy;
import com.ecoolex.chinadutyfree.retailer.enums.CouponClassStatus;
import com.ecoolex.chinadutyfree.retailer.pojo.EditCouponClassOneStep;
import com.ecoolex.chinadutyfree.retailer.pojo.EditCouponClassTwoStep;
import com.ecoolex.chinadutyfree.retailer.pojo.QueryCouponClassDTO;
import com.ecoolex.chinadutyfree.retailer.pojo.QueryCouponDTO;
import com.ecoolex.chinadutyfree.retailer.ws.CouponService;
import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.common.util.Assert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.modularize.api.auth.admin.AdminMemberAuthority;
import com.ecoolex.framework.modularize.api.auth.annotation.AdminAuthoritativeRegister;
import com.ecoolex.framework.modularize.api.auth.user.ConsumerMember;
import com.ecoolex.framework.modularize.api.auth.user.ConsumerMemberManager;
import com.ecoolex.framework.modularize.api.service.currency.CurrencyType;
import com.ecoolex.framework.modularize.api.service.currency.CurrencyTypeService;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module;
import com.ecoolex.framework.web.api.graphql2.annotation.MutationField;
import com.ecoolex.framework.web.api.graphql2.annotation.QueryField;
import com.ecoolex.framework.web.api.graphql2.annotation.Source;
import com.ecoolex.framework.web.api.graphql2.annotation.TypeField;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module.Type;

@GraphQL2Module(type = Type.Admin, description = "优惠券")
@AdminAuthoritativeRegister(parentKey = AdminConstant.AUTH_MODULE_KEY,
	key = CouponGraphql.AUTH,
	name = "优惠券管理",
	remark = "优惠券管理")
public class CouponGraphql {

	public static final String AUTH = AdminConstant.AUTH_PROJECT_KEY + "-COUPON";
	
	@Reference
	private CouponService couponService;
	
	@Autowired
	private CurrencyTypeService currencyTypeService;
	
	@Autowired
	private ConsumerMemberManager consumer;
	
	@TypeField(type = CouponClass.class, field = "currencyType", description = "币种")
	public CurrencyType currencyType(@Source CouponClass source) {
		return currencyTypeService.get(source.getCurrencyType());
	}
	
	@TypeField(type = CouponClass.class, field = "canEdit", description = "是否能编辑")
	public Boolean canEdit(@Source CouponClass couponClass, AdminMemberAuthority user) {
		return user.auth(AUTH_EDIT);
	}

	@TypeField(type = CouponClass.class, field = "canDel", description = "是否能删除")
	public Boolean canDel(@Source CouponClass couponClass, AdminMemberAuthority user) {
		return user.auth(AUTH_DEL) && (Check.eq(couponClass.getStatus(), CouponClassStatus.EDITING.real())
			|| Check.eq(couponClass.getStatus(), CouponClassStatus.EDITED.real())
			|| Check.eq(couponClass.getStatus(), CouponClassStatus.INVALID.real()));
	}

	@TypeField(type = CouponClass.class, field = "canOnline", description = "是否能上线")
	public Boolean canOnline(@Source CouponClass couponClass, AdminMemberAuthority user) {
		return user.auth(AUTH_ONLINE) && Check.eq(couponClass.getStatus(), CouponClassStatus.EDITED.real());
	}

	@TypeField(type = CouponClass.class, field = "canInvalid", description = "能作废")
	public Boolean canInvalid(@Source CouponClass couponClass, AdminMemberAuthority user) {
		return user.auth(AUTH_INVALID) && Check.eq(couponClass.getStatus(), CouponClassStatus.ONLINE.real());
	}
	
	@TypeField(type = CouponClass.class, field = "canEditProvideNumber", description = "能发放数量")
	public Boolean canEditProvideNumber(@Source CouponClass couponClass, AdminMemberAuthority user) {
		return user.auth(AUTH_PROVIDE_NUMBER_EDIT)
			&& Check.eq(couponClass.getProvideStrategy(), CouponClassProvideStrategy.LIMIT.real())
			&& Check.eq(couponClass.getStatus(), CouponClassStatus.ONLINE.real());
	}
	
	@TypeField(type = CouponClass.class, field = "expireStrategy", description = "优惠券过期策略")
	public CouponClassExpireStrategy expireStrategy(@Source CouponClass couponClass) {
		return couponService.getCouponClassExpireStrategyById(couponClass.getCouponClassId());
	}
	
	@TypeField(type = Coupon.class, field = "couponClass", description = "优惠券类")
	public CouponClass couponClass(@Source Coupon source) {
		return couponService.getCouponClassById(source.getCouponClassId());
	}
	
	@TypeField(type = Coupon.class, field = "couponVerifyingConsumption", description = "商户优惠券核销记录")
	public CouponVerifyingConsumption couponVerifyingConsumption(@Source Coupon source) {
		return couponService.getCouponVerifyingConsumptionByCouponId(source.getCouponId());
	}
	
	@TypeField(type = Coupon.class, field = "consumerUser", description = "消费者用户")
	public ConsumerMember consumerUser(@Source Coupon source) {
		return consumer.getByUserId(source.getUserId());
	}
	
	private static final String AUTH_COUPON_QUERY = AUTH + "-COUPON-QUERY";
	
	@QueryField(field = "couponList", description = "用户优惠券领取列表")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_COUPON_QUERY, name = "用户优惠券领取列表")
	public Pagination<Coupon> couponList(@NonNull QueryCouponDTO query,@NonNull Sorting[] sorts,@NonNull Page page,AdminMemberAuthority user){
		user.assertAuth(AUTH_COUPON_QUERY);
		return couponService.couponList(query, sorts, page);
	}
	
	private static final String AUTH_QUERY = AUTH + "-QUERY";
	
	@QueryField(field = "couponClassList", description = "优惠券列表")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_QUERY, name = "查询优惠券列表")
	public Pagination<CouponClass> query(@NonNull QueryCouponClassDTO query, @NonNull Page page, AdminMemberAuthority user) {
		user.assertAuth(AUTH_QUERY);
		return couponService.queryCouponClass(query, page);
	}

	private static final String AUTH_GET = AUTH + "-GET";
	
	@QueryField(field = "couponClass", description = "优惠券详情")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_GET, name = "获取优惠券详情")
	public CouponClass get(@NonNull Integer couponClassId, AdminMemberAuthority user) {
		user.assertAuth(AUTH_GET);
		return couponService.getCouponClassById(couponClassId);
	}
	
	private static final String AUTH_EDIT = AUTH + "-EDIT";

	@MutationField(field = "editCouponClass",
		description = { "编辑优惠券",
			"每一步传递相应的参数对象, 默认传null" })
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_EDIT, name = "编辑优惠券")
	public CouponClass updateCouponClassStep(EditCouponClassOneStep one, EditCouponClassTwoStep two, AdminMemberAuthority user) {
		user.assertAuth(AUTH_EDIT);
		if (Check.notNull(one)) {
			return couponService.updateCouponClassStep(one, user.userName());
		} else if (Check.notNull(two)) {
			return couponService.updateCouponClassStep(two, user.userName());
		}
		Assert.throwVerifyException("没有步数据");
		return null;
	}

	private static final String AUTH_DEL = AUTH + "-DEL";

	@MutationField(field = "delCouponClass", description = { "删除优惠券" })
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_DEL, name = "删除优惠券")
	public Boolean deleteCouponClass(@NonNull Integer couponClassId, AdminMemberAuthority user) {
		user.assertAuth(AUTH_DEL);
		Assert.isTrue(Check.notNull(couponClassId), ResultCode.VERIFY.build(1), "优惠券id为空");
		CouponClass couponClass = couponService.getCouponClassById(couponClassId);
		Assert.isTrue(Check.notNull(couponClass), ResultCode.VERIFY.build(2), "优惠券为空");
		Assert.isTrue(Check.notEq(couponClass.getStatus(), CouponClassStatus.ONLINE.real()),
			ResultCode.VERIFY.build(3),
			"优惠券必须非上线状态");
		couponService.deleteCouponClass(couponClass, user.userName());
		return true;
	}

	private static final String AUTH_ONLINE = AUTH + "-ONLINE";

	@MutationField(field = "onlineCouponClass", description = { "优惠券上线" })
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_ONLINE, name = "优惠券上线")
	public Boolean onlineCouponClass(@NonNull Integer couponClassId, AdminMemberAuthority user) {
		user.assertAuth(AUTH_ONLINE);
		Assert.isTrue(Check.notNull(couponClassId), ResultCode.VERIFY.build(1), "优惠券id为空");
		CouponClass couponClass = couponService.getCouponClassById(couponClassId);
		Assert.isTrue(Check.notNull(couponClass), ResultCode.VERIFY.build(3), "优惠券为空");
		Assert.isTrue(Check.eq(couponClass.getStatus(), CouponClassStatus.EDITED.real()),
			ResultCode.VERIFY.build(5),
			"优惠券必须编辑完成状态");

		couponService.onlineCouponClass(couponClass, user.userName());
		return true;
	}

	private static final String AUTH_INVALID = AUTH + "-INVALID";

	@MutationField(field = "invalidCouponClass", description = { "优惠券作废" })
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_INVALID, name = "优惠券作废")
	public Boolean offlineCouponClass(@NonNull Integer couponClassId, AdminMemberAuthority user) {
		user.assertAuth(AUTH_INVALID);
		Assert.isTrue(Check.notNull(couponClassId), ResultCode.VERIFY.build(1), "优惠券id为空");
		CouponClass couponClass = couponService.getCouponClassById(couponClassId);
		Assert.isTrue(Check.notNull(couponClass), ResultCode.VERIFY.build(3), "优惠券为空");
		Assert.isTrue(Check.eq(couponClass.getStatus(), CouponClassStatus.ONLINE.real()),
			ResultCode.VERIFY.build(5),
			"优惠券必须上线状态");

		couponService.invalidCouponClass(couponClass, user.userName());
		return true;
	}

	private static final String AUTH_PROVIDE_NUMBER_EDIT = AUTH + "-PROVIDE-NUMBER-EDIT";

	@MutationField(field = "editCouponClassProvideNumber", description = { "编辑优惠券发放数量" })
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_PROVIDE_NUMBER_EDIT, name = "编辑优惠券发放数量")
	public Boolean editCouponClassProvideNumber(@NonNull Integer couponClassId, @NonNull Integer newProvideNumber, AdminMemberAuthority user) {
		user.assertAuth(AUTH_PROVIDE_NUMBER_EDIT);
		Assert.isTrue(Check.notNull(couponClassId), ResultCode.VERIFY.build(1), "优惠券id为空");
		Assert.isTrue(Check.notNullAndGtZero(newProvideNumber), ResultCode.VERIFY.build(2), "发放数量不能小于1");
		CouponClass couponClass = couponService.getCouponClassById(couponClassId);
		Assert.isTrue(Check.notNull(couponClass), ResultCode.VERIFY.build(3), "优惠券为空");
		Assert.isTrue(Check.eq(couponClass.getProvideStrategy(), CouponClassProvideStrategy.LIMIT.real()),
			ResultCode.VERIFY.build(4),
			"发放策略必须为限制");
		Assert.isTrue(Check.eq(couponClass.getStatus(), CouponClassStatus.ONLINE.real()),
			ResultCode.VERIFY.build(5),
			"优惠券必须是上线状态");
		couponService.updateCouponClassProvideNumber(couponClass, newProvideNumber, user.userName());
		return true;
	}
}
